from threading import Thread
from socket import *
import sys
import os
from time import sleep

FTP = "/home/tarena/FTP/"


class Select:
    def __init__(self, conn):
        self.conn = conn

    def do_list(self):
        files = os.listdir(FTP)
        if files:
            self.conn.send(b'OK')
            sleep(0.1)
            data = "\n".join(files)
            self.conn.send(data.encode())
        else:
            self.conn.send('文件库为空'.encode())


class Download:
    def __init__(self, conn):
        self.conn = conn

    def do_retr(self, filename):
        try:
            fr = open(FTP + filename, 'rb')
        except:
            self.conn.send('找不到该文件'.encode())
        else:
            self.conn.send(b'OK')
            sleep(0.1)  # 防止粘包
            # 发送文件
            while True:
                data = fr.read(1024)
                if not data:
                    break
                self.conn.send(data)
            fr.close()
            sleep(0.1)  # 防止粘包
            self.conn.send(b'##')

class Upload:
    def __init__(self, conn):
        self.conn = conn

    def do_stor(self,filename):
        if os.path.exists(FTP + filename):
            self.conn.send('已存在该文件'.encode())
        else:
            self.conn.send(b'OK')
            fw = open(FTP + filename, 'wb')
            # 接收文件
            while True:
                data = self.conn.recv(1024)
                if data == b"##":
                    break
                fw.write(data)
            fw.close()


class ThreadHandle(Thread):

    def __init__(self, conn):
        self.conn = conn
        self.select = Select(self.conn)
        self.upload = Upload(self.conn)
        self.download = Download(self.conn)
        super().__init__(daemon=True)

    def run(self):
        while True:
            request = self.conn.recv(1024).decode()
            tmp = request.split(' ')
            if not request:
                break
            if tmp[0] == "LIST":
                self.select.do_list()
            elif tmp[0] == "RETR":
                self.download.do_retr(tmp[1])
            elif tmp[0] == "STOR":
                self.upload.do_stor(tmp[1])
        self.conn.close()


class FTPServer:
    def __init__(self, host='', port=0):
        self.host = host
        self.port = port
        self.address = (self.host, self.port)
        self.sock = self._create_socket()

    def _create_socket(self):
        sock = socket()
        sock.bind(self.address)
        return sock

    def serve_forever(self):
        self.sock.listen(5)
        print("Listen the port %d" % self.port)
        while True:
            try:
                conn, addr = self.sock.accept()
                print("Connect from", addr)
            except KeyboardInterrupt:
                sys.exit("服务端退出")
            t = ThreadHandle(conn)
            t.start()


if __name__ == '__main__':
    ftp = FTPServer(host="0.0.0.0", port=12120)
    ftp.serve_forever()
